package com.livestocksolutions;

import java.util.Date;
import java.util.HashMap;

import com.livestocksolutions.util.UpdateHistory;
/**
 * Base class for acquisition and deacquisition. This class basically records information about the movement of cows to and from the farm
 *
 * @author Matt Lang
 */
public class ADcquisition {
	/**
	 * Keep track of any changes, until this GroupHistory is assigned to an owner.
	 */
	protected HashMap<String,UpdateHistory> update = new HashMap<String,UpdateHistory>();
	/**
	 * Date of which this Animal was acquired/disacquired
	 */
	protected long date;
	/**
	 * describes how the cow was acquired/disacquired
	 */
	private String method;
	/**
	 * price paid/sold for
	 */
	private float price;
	/**
	 * person bought from/sold to
	 */
	private long owner;
	
	/**
	 * Constructor
	 * @param method String describing method
	 * @param price int price paid/sold for
	 * @param owner person bought from/sold to
	 */
	public ADcquisition(String method, float price, Owner owner)
	{
		this.method = method;
		this.owner=owner!=null?owner.getID():0;
		date = new Date().getTime();
		this.price = price;
		
		update.put("METHOD", new UpdateHistory(this.method));
		update.put("OWNER", new UpdateHistory(String.valueOf(this.owner)));
		update.put("DATE", new UpdateHistory(String.valueOf(date)));
		update.put("PRICE", new UpdateHistory(String.valueOf(this.price)));
	}
	
	/**
	 * Constructor
	 * @param method String describing method
	 * @param price Int price paid/sold for
	 * @param owner Person bought from/sold to
	 * @param date Date of the purchase/sale
	 */
	public ADcquisition(String method, float price, Owner owner, Date date)
	{
		this.method = method;
		this.owner=owner!=null?owner.getID():0;
		this.date = date!=null?date.getTime():0;
		this.price = price;
		
		update.put("METHOD", new UpdateHistory(this.method));
		update.put("OWNER", new UpdateHistory(String.valueOf(this.owner)));
		update.put("DATE", new UpdateHistory(String.valueOf(this.date)));
		update.put("PRICE", new UpdateHistory(String.valueOf(this.price)));
	}

	/**
	 * Accessor for the method attribute
	 * @return The method this animal was acquired or de-acquired
	 */
	public String getMethod() 
	{
		return method;
	}
	
	/**
	 * Accessor for the price attribute
	 * @return The price of the purchase or sale or 0 if not a purchase or sale.
	 */
	public float getPrice(){
		return price;
	}

	/**
	 * Accessor for the owner attribute
	 * @return The Owner associated with this acquisition or deacquisition.
	 */
	public Owner getOwner(){
		return LivestockSolutions.getOwnerByID(owner);
	}
	
	/**
	 * Get the date that this Object was created.
	 * @return The date of acquisition or deacquisition.
	 */
	public Date getDate(){
		return date==0?null:new Date(date);
	}
	
	/**
	 * Updates this Object with the updated values from the different version.
	 * @param changes ADcquisition that represents this Object in a different version.
	 * @return <tt>true</tt> if changes is not null and changes does not equal this object, <tt>false</tt> otherwise.
	 */
	public boolean update(ADcquisition changes){
		if(changes!=null && this!=changes){
			if(updateBefore("OWNER",changes)){
				owner=Long.parseLong(changes.update.get("OWNER").getValue());
				update.put("OWNER", new UpdateHistory(String.valueOf(owner)));
			}
			
			if(updateBefore("METHOD",changes)){
				method=changes.update.get("METHOD").getValue();
				update.put("METHOD", new UpdateHistory(method));
			}
			
			if(updateBefore("DATE",changes)){
				date=Long.parseLong(changes.update.get("DATE").getValue());
				update.put("DATE", new UpdateHistory(String.valueOf(date)));
			}
			
			if(updateBefore("PRICE",changes)){
				price=Float.parseFloat(changes.update.get("PRICE").getValue());
				update.put("PRICE", new UpdateHistory(String.valueOf(price)));
			}
			return true;
		}
		return false;
	}
	
	/**
	 * Checks to see if the modification date of the item at this position is before the changed value
	 * @param key The String key at which to compare the modification dates of the modified objects.
	 * @param changes The ADcquisition that represents this ADcquisition on another system.
	 * @return <tt>true</tt> if the old value was modified before the changed value. <tt>false</tt> otherwise.
	 */
	protected boolean updateBefore(String key,ADcquisition changes){
		if(this.update.get(key)==null && changes.update.get(key)!=null){
			return true;
		}else if(changes.update.get(key)==null){
			return false;
		}
		return !this.update.get(key).getDate().after(changes.update.get(key).getDate());
	}
}//end class
